package com.ruoyi.pack.service.impl;

import java.util.List;
import java.util.Date;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.pack.mapper.PackTransferRecordMapper;
import com.ruoyi.pack.mapper.PackWarehouseMapper;
import com.ruoyi.pack.domain.PackTransferRecord;
import com.ruoyi.pack.domain.PackContainer;
import com.ruoyi.pack.domain.PackWarehouse;
import com.ruoyi.pack.domain.dto.PackContainerWarehouseInfoDTO;
import com.ruoyi.pack.service.IPackTransferRecordService;

/**
 * 移库记录Service业务层处理
 * 
 * @author ruoyi
 * @date 2024-01-01
 */
@Service
public class PackTransferRecordServiceImpl implements IPackTransferRecordService 
{
    private static final Logger logger = LoggerFactory.getLogger(PackTransferRecordServiceImpl.class);
    
    @Autowired
    private PackTransferRecordMapper packTransferRecordMapper;
    
    @Autowired
    private PackWarehouseMapper packWarehouseMapper;

    /**
     * 查询移库记录
     * 
     * @param transferId 移库记录主键
     * @return 移库记录
     */
    @Override
    public PackTransferRecord selectPackTransferRecordByTransferId(Long transferId)
    {
        return packTransferRecordMapper.selectPackTransferRecordByTransferId(transferId);
    }

    /**
     * 查询移库记录列表
     * 
     * @param packTransferRecord 移库记录
     * @return 移库记录
     */
    @Override
    public List<PackTransferRecord> selectPackTransferRecordList(PackTransferRecord packTransferRecord)
    {
        return packTransferRecordMapper.selectPackTransferRecordList(packTransferRecord);
    }

    /**
     * 新增移库记录
     * 
     * @param packTransferRecord 移库记录
     * @return 结果
     */
    @Override
    @Transactional
    public int insertPackTransferRecord(PackTransferRecord packTransferRecord)
    {
        // 设置创建时间和移库时间
        Date now = DateUtils.getNowDate();
        packTransferRecord.setCreateTime(now);
        if (packTransferRecord.getTransferTime() == null) {
            packTransferRecord.setTransferTime(now);
        }
        
        // 如果是手动移库，需要填充冗余字段
        if ("0".equals(packTransferRecord.getAutoGenerated())) {
            fillTransferRecordData(packTransferRecord);
        }
        
        // 设置操作员信息
        if (StringUtils.isNotEmpty(packTransferRecord.getCreateBy())) {
            packTransferRecord.setOperatorName(packTransferRecord.getCreateBy());
        }
        
        return packTransferRecordMapper.insertPackTransferRecord(packTransferRecord);
    }
    
    /**
     * 填充移库记录的冗余数据
     */
    private void fillTransferRecordData(PackTransferRecord packTransferRecord) {
        try {
            // 获取器具信息
            if (packTransferRecord.getContainerId() != null) {
                // 这里应该调用容器服务获取器具信息，但为了避免循环依赖，暂时跳过
                // 在实际使用中，前端应该传入完整的器具信息
            }
            
            // 获取仓库信息
            if (packTransferRecord.getSourceWarehouseId() != null && StringUtils.isEmpty(packTransferRecord.getSourceWarehouseName())) {
                PackWarehouse sourceWarehouse = packWarehouseMapper.selectPackWarehouseByWarehouseId(packTransferRecord.getSourceWarehouseId());
                if (sourceWarehouse != null) {
                    packTransferRecord.setSourceWarehouseName(sourceWarehouse.getWarehouseName());
                }
            }
            
            if (packTransferRecord.getTargetWarehouseId() != null && StringUtils.isEmpty(packTransferRecord.getTargetWarehouseName())) {
                PackWarehouse targetWarehouse = packWarehouseMapper.selectPackWarehouseByWarehouseId(packTransferRecord.getTargetWarehouseId());
                if (targetWarehouse != null) {
                    packTransferRecord.setTargetWarehouseName(targetWarehouse.getWarehouseName());
                }
            }
            
        } catch (Exception e) {
            logger.error("填充移库记录数据时发生错误", e);
        }
    }

    /**
     * 修改移库记录
     * 
     * @param packTransferRecord 移库记录
     * @return 结果
     */
    @Override
    public int updatePackTransferRecord(PackTransferRecord packTransferRecord)
    {
        packTransferRecord.setUpdateTime(DateUtils.getNowDate());
        return packTransferRecordMapper.updatePackTransferRecord(packTransferRecord);
    }

    /**
     * 批量删除移库记录
     * 
     * @param transferIds 需要删除的移库记录主键
     * @return 结果
     */
    @Override
    public int deletePackTransferRecordByTransferIds(Long[] transferIds)
    {
        return packTransferRecordMapper.deletePackTransferRecordByTransferIds(transferIds);
    }

    /**
     * 删除移库记录信息
     * 
     * @param transferId 移库记录主键
     * @return 结果
     */
    @Override
    public int deletePackTransferRecordByTransferId(Long transferId)
    {
        return packTransferRecordMapper.deletePackTransferRecordByTransferId(transferId);
    }

    /**
     * 创建器具出库记录
     * 
     * @param container 器具信息
     * @param sourceWarehouseId 来源仓库ID
     * @param sourceWarehouseName 来源仓库名称
     * @param targetWarehouseId 目标仓库ID（可为空，表示不确定目标）
     * @param targetWarehouseName 目标仓库名称（可为空）
     * @param locationLogId 触发的定位日志ID
     * @param operatorName 操作员姓名
     * @return 移库记录ID
     */
    @Override
    @Transactional
    public Long createOutboundRecord(PackContainer container, 
                                   Long sourceWarehouseId, 
                                   String sourceWarehouseName,
                                   Long targetWarehouseId,
                                   String targetWarehouseName,
                                   Long locationLogId,
                                   String operatorName)
    {
        // 如果来源仓库名称为空，尝试从数据库查询
        if (StringUtils.isEmpty(sourceWarehouseName) && sourceWarehouseId != null) {
            PackWarehouse sourceWarehouse = packWarehouseMapper.selectPackWarehouseByWarehouseId(sourceWarehouseId);
            if (sourceWarehouse != null) {
                sourceWarehouseName = sourceWarehouse.getWarehouseName();
            }
        }
        
        // 如果目标仓库名称为空且目标仓库ID不为空，尝试从数据库查询
        if (StringUtils.isEmpty(targetWarehouseName) && targetWarehouseId != null) {
            PackWarehouse targetWarehouse = packWarehouseMapper.selectPackWarehouseByWarehouseId(targetWarehouseId);
            if (targetWarehouse != null) {
                targetWarehouseName = targetWarehouse.getWarehouseName();
            }
        }
        
        // 创建移库记录
        PackTransferRecord transferRecord = new PackTransferRecord();
        
        // 器具基本信息
        transferRecord.setContainerId(container.getContainerId());
        transferRecord.setContainerCode(container.getContainerCode());
        transferRecord.setContainerModelCode(container.getMaterialCode());
        transferRecord.setContainerModelName(container.getMaterialName());
        
        // 项目信息
        transferRecord.setProjectId(container.getCurrentProjectId());
        transferRecord.setProjectCode(container.getCurrentProjectCode());
        transferRecord.setProjectName(container.getCurrentProjectName());
        
        // 物料信息（满箱移库时才有）
        if ("2".equals(container.getPackingStatus())) {
            transferRecord.setMaterialCode(container.getCurrentMaterialCode());
            transferRecord.setMaterialName(container.getCurrentMaterialName());
            transferRecord.setMaterialQuantity(container.getCurrentMaterialQuantity());
            transferRecord.setLiningScheme(container.getCurrentLiningScheme());
            transferRecord.setTransferType("1"); // 满箱移库
        } else {
            transferRecord.setTransferType("2"); // 空箱移库
        }
        
        // 仓库信息
        transferRecord.setSourceWarehouseId(sourceWarehouseId);
        transferRecord.setSourceWarehouseName(sourceWarehouseName);
        transferRecord.setTargetWarehouseId(targetWarehouseId);
        transferRecord.setTargetWarehouseName(targetWarehouseName);
        
        // 移库信息
        transferRecord.setTransferStage("1"); // 出库阶段
        transferRecord.setTransferTime(DateUtils.getNowDate());
        transferRecord.setAutoGenerated("1"); // 自动生成
        transferRecord.setLocationLogId(locationLogId);
        
        // 操作员信息
        try {
            transferRecord.setOperatorId(SecurityUtils.getUserId());
            transferRecord.setOperatorName(StringUtils.isNotEmpty(operatorName) ? operatorName : SecurityUtils.getUsername());
        } catch (Exception e) {
            // 系统自动触发时可能没有登录用户
            transferRecord.setOperatorName("系统自动");
        }
        
        // 审计信息
        transferRecord.setCreateBy(transferRecord.getOperatorName());
        transferRecord.setCreateTime(DateUtils.getNowDate());
        transferRecord.setDelFlag("0");
        
        // 保存记录
        int result = packTransferRecordMapper.insertPackTransferRecord(transferRecord);
        if (result > 0) {
            logger.info("创建出库记录成功，器具编码: {}, 来源仓库: {}, 目标仓库: {}, 移库记录ID: {}", 
                       container.getContainerCode(), sourceWarehouseName, targetWarehouseName, transferRecord.getTransferId());
            return transferRecord.getTransferId();
        }
        
        logger.error("创建出库记录失败，器具编码: {}", container.getContainerCode());
        return null;
    }

    /**
     * 创建器具入库记录（更新已有出库记录或创建新入库记录）
     * 
     * @param container 器具信息
     * @param targetWarehouse 目标仓库信息
     * @param locationLogId 触发的定位日志ID
     * @param operatorName 操作员姓名
     * @return 移库记录ID
     */
    @Override
    @Transactional
    public Long createInboundRecord(PackContainer container,
                                  PackContainerWarehouseInfoDTO targetWarehouse,
                                  Long locationLogId,
                                  String operatorName)
    {
        // 1. 先查找是否有未完成的出库记录
        PackTransferRecord outboundRecord = packTransferRecordMapper.selectLatestOutboundRecordByContainerId(container.getContainerId());
        
        PackTransferRecord inboundRecord = new PackTransferRecord();
        
        // 器具基本信息
        inboundRecord.setContainerId(container.getContainerId());
        inboundRecord.setContainerCode(container.getContainerCode());
        inboundRecord.setContainerModelCode(container.getMaterialCode());
        inboundRecord.setContainerModelName(container.getMaterialName());
        
        // 项目信息（使用目标仓库关联的项目信息）
        inboundRecord.setProjectId(targetWarehouse.getProjectId());
        inboundRecord.setProjectCode(targetWarehouse.getProjectCode());
        inboundRecord.setProjectName(targetWarehouse.getProjectName());
        
        // 物料信息（满箱移库时才有）
        if ("2".equals(container.getPackingStatus())) {
            inboundRecord.setMaterialCode(container.getCurrentMaterialCode());
            inboundRecord.setMaterialName(container.getCurrentMaterialName());
            inboundRecord.setMaterialQuantity(container.getCurrentMaterialQuantity());
            inboundRecord.setLiningScheme(container.getCurrentLiningScheme());
            inboundRecord.setTransferType("1"); // 满箱移库
        } else {
            inboundRecord.setTransferType("2"); // 空箱移库
        }
        
        // 仓库信息
        inboundRecord.setTargetWarehouseId(targetWarehouse.getWarehouseId());
        inboundRecord.setTargetWarehouseName(targetWarehouse.getWarehouseName());
        
        if (outboundRecord != null) {
            // 2. 如果有出库记录，创建关联的入库记录
            inboundRecord.setSourceWarehouseId(outboundRecord.getSourceWarehouseId());
            inboundRecord.setSourceWarehouseName(outboundRecord.getSourceWarehouseName());
            inboundRecord.setParentTransferId(outboundRecord.getTransferId());
            
            // 如果出库记录的目标仓库为空，更新出库记录的目标仓库信息
            if (outboundRecord.getTargetWarehouseId() == null) {
                outboundRecord.setTargetWarehouseId(targetWarehouse.getWarehouseId());
                outboundRecord.setTargetWarehouseName(targetWarehouse.getWarehouseName());
                outboundRecord.setUpdateBy(inboundRecord.getOperatorName());
                outboundRecord.setUpdateTime(DateUtils.getNowDate());
                packTransferRecordMapper.updatePackTransferRecord(outboundRecord);
            }
        } else {
            // 3. 如果没有出库记录，表示器具初次入库或者是从外部直接进入
            inboundRecord.setSourceWarehouseId(null);
            inboundRecord.setSourceWarehouseName(null);
            inboundRecord.setParentTransferId(null);
        }
        
        // 移库信息
        inboundRecord.setTransferStage("2"); // 入库阶段
        inboundRecord.setTransferTime(DateUtils.getNowDate());
        inboundRecord.setAutoGenerated("1"); // 自动生成
        inboundRecord.setLocationLogId(locationLogId);
        
        // 操作员信息
        try {
            inboundRecord.setOperatorId(SecurityUtils.getUserId());
            inboundRecord.setOperatorName(StringUtils.isNotEmpty(operatorName) ? operatorName : SecurityUtils.getUsername());
        } catch (Exception e) {
            // 系统自动触发时可能没有登录用户
            inboundRecord.setOperatorName("系统自动");
        }
        
        // 审计信息
        inboundRecord.setCreateBy(inboundRecord.getOperatorName());
        inboundRecord.setCreateTime(DateUtils.getNowDate());
        inboundRecord.setDelFlag("0");
        
        // 保存记录
        int result = packTransferRecordMapper.insertPackTransferRecord(inboundRecord);
        if (result > 0) {
            logger.info("创建入库记录成功，器具编码: {}, 目标仓库: {}, 移库记录ID: {}, 关联出库记录ID: {}", 
                       container.getContainerCode(), targetWarehouse.getWarehouseName(), 
                       inboundRecord.getTransferId(), inboundRecord.getParentTransferId());
            return inboundRecord.getTransferId();
        }
        
        logger.error("创建入库记录失败，器具编码: {}", container.getContainerCode());
        return null;
    }

    /**
     * 根据器具ID查询最新的未完成移库记录（出库阶段且没有对应的入库记录）
     * 
     * @param containerId 器具ID
     * @return 移库记录
     */
    @Override
    public PackTransferRecord selectLatestOutboundRecordByContainerId(Long containerId)
    {
        return packTransferRecordMapper.selectLatestOutboundRecordByContainerId(containerId);
    }

    /**
     * 根据器具ID查询移库记录列表
     * 
     * @param containerId 器具ID
     * @return 移库记录集合
     */
    @Override
    public List<PackTransferRecord> selectPackTransferRecordListByContainerId(Long containerId)
    {
        return packTransferRecordMapper.selectPackTransferRecordListByContainerId(containerId);
    }

    /**
     * 根据父移库记录ID查询入库记录
     * 
     * @param parentTransferId 父移库记录ID
     * @return 移库记录
     */
    @Override
    public PackTransferRecord selectInboundRecordByParentTransferId(Long parentTransferId)
    {
        return packTransferRecordMapper.selectInboundRecordByParentTransferId(parentTransferId);
    }

    /**
     * 查询器具的完整移库链路
     * 
     * @param containerId 器具ID
     * @param startTime 开始时间
     * @param endTime 结束时间
     * @return 移库记录集合
     */
    @Override
    public List<PackTransferRecord> selectContainerTransferChain(Long containerId, String startTime, String endTime)
    {
        return packTransferRecordMapper.selectContainerTransferChain(containerId, startTime, endTime);
    }

    /**
     * 统计指定时间范围内的移库次数
     * 
     * @param startTime 开始时间
     * @param endTime 结束时间
     * @param transferType 移库类型
     * @param transferStage 移库阶段
     * @return 移库次数
     */
    @Override
    public int countTransferRecordsByTimeRange(String startTime, String endTime, String transferType, String transferStage)
    {
        return packTransferRecordMapper.countTransferRecordsByTimeRange(startTime, endTime, transferType, transferStage);
    }

    /**
     * 更新器具的出库记录为入库完成状态
     * 
     * @param containerId 器具ID
     * @param targetWarehouseId 目标仓库ID
     * @param targetWarehouseName 目标仓库名称
     * @param targetProjectId 目标项目ID
     * @param targetProjectCode 目标项目编码
     * @param targetProjectName 目标项目名称
     * @param inboundLocationLogId 入库定位日志ID
     * @param operatorName 操作员姓名
     * @return 是否更新成功
     */
    @Override
    @Transactional
    public boolean updateToInboundRecord(Long containerId,
                                       Long targetWarehouseId,
                                       String targetWarehouseName,
                                       Long targetProjectId,
                                       String targetProjectCode,
                                       String targetProjectName,
                                       Long inboundLocationLogId,
                                       String operatorName)
    {
        try {
            // 1. 查找该器具最新的出库记录（阶段为1且没有完成入库的记录）
            PackTransferRecord outboundRecord = selectLatestOutboundRecordByContainerId(containerId);
            
            if (outboundRecord == null) {
                logger.warn("未找到器具[{}]的待完成出库记录", containerId);
                return false;
            }
            
            // 2. 更新记录为入库完成状态
            PackTransferRecord updateRecord = new PackTransferRecord();
            updateRecord.setTransferId(outboundRecord.getTransferId());
            
            // 设置目标仓库信息
                    updateRecord.setTargetWarehouseId(targetWarehouseId);
        updateRecord.setTargetWarehouseName(targetWarehouseName);
        updateRecord.setProjectId(targetProjectId);
        updateRecord.setProjectCode(targetProjectCode);
        updateRecord.setProjectName(targetProjectName);
            
                    // 设置移库阶段为2（入库）
        updateRecord.setTransferStage("2");

        // 设置入库相关信息
        updateRecord.setLocationLogId(inboundLocationLogId);
        updateRecord.setTransferTime(DateUtils.getNowDate());
            updateRecord.setUpdateTime(DateUtils.getNowDate());
            updateRecord.setUpdateBy(operatorName);
            
            // 执行更新
            int result = packTransferRecordMapper.updatePackTransferRecord(updateRecord);
            
            if (result > 0) {
                logger.info("成功更新器具[{}]的移库记录[{}]为入库完成状态", containerId, outboundRecord.getTransferId());
                return true;
            } else {
                logger.warn("更新器具[{}]的移库记录[{}]失败", containerId, outboundRecord.getTransferId());
                return false;
            }
            
        } catch (Exception e) {
            logger.error("更新器具[{}]移库记录为入库状态时发生异常: {}", containerId, e.getMessage(), e);
            return false;
        }
    }
} 